package t10086.Controller;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import t10086.Data.Pop.PopMsg;
import t10086.Data.Pop.PopType;
import t10086.Data.Robot.RobotType;
import t10086.Model.Entity.DeliveryRecord;
import t10086.Model.Http.Response;
import t10086.Model.Messages.Message;
import t10086.Model.Messages.MessageType;
import t10086.Service.DeliveryRecordService;
import t10086.Service.OrderService;
import t10086.WorkThread.MsgConvertHandler;
import t10086.WorkThread.Shared.DataBuffer;
import t10086.WorkThread.ThreadPoolManager;

import java.util.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

@RestController
@RequestMapping("/delivery_record")
public class DeliveryRecordController {

    private final DeliveryRecordService deliveryRecordService;
    private final OrderService orderService;
    private final static  BlockingQueue<Message> blockingQueue=new LinkedBlockingQueue<Message>();;
    public static void putMessage(Message message) {
        try {
            blockingQueue.put(message);
        } catch (InterruptedException e) {
            System.out.println(e.getMessage());
        }
    }

    @Scheduled(fixedDelay = 3000)
    public void handleDeliveryRecord() {
        if(blockingQueue.isEmpty()) {
            return;
        }
        Message message = blockingQueue.poll();
        Map<String,Object> data = (Map<String, Object>) message.getData();
        String orderNumber = (String) data.get("orderNumber");
        String serialNumber = (String) data.get("serialNumber");
        int window = (int) data.get("window");
        long deliveryTime = (long) data.get("deliveryTime");
        if(orderNumber==null || serialNumber==null) {
            System.out.println("orderNumber,serialNumber,window,deliveryTime null");
            return;
        }
        System.out.println(orderNumber+","+serialNumber+","+window+","+deliveryTime);

//        int windowI = Integer.parseInt(window);
//        int deliveryI = Integer.parseInt(deliveryTime);
        orderService.setOrderStatus(orderNumber,1);
        deliveryRecordService.updateDeliveryRecord(orderNumber,serialNumber,window,1,(int)deliveryTime);
        LinkedList<Message> msgQueue =new LinkedList<>();
        msgQueue.add(new Message(message.getReceiver(),message.getNext(), MessageType.RESPONSE,""));
//        synchronized (DataBuffer.class) {
            DataBuffer.getBroadcast().addPopMsg(new PopMsg(
                    PopType.DELIVER,
                    RobotType.ROBOT,
                    serialNumber,
                    "Finished Order "+orderNumber
            ));
//        }
        ThreadPoolManager.submitTask(new MsgConvertHandler(msgQueue));
    }
    @Autowired
    public DeliveryRecordController(DeliveryRecordService deliveryRecordService,OrderService orderService) {
        this.deliveryRecordService = deliveryRecordService;
        this.orderService = orderService;
    }

    public boolean StringIsNull(String data){
        return data==null|| data.isEmpty();
    }

    @GetMapping("/deliver_start")
    public Response getDeliverStartOrders(@RequestParam(name = "orderNumber") String orderNumber,
                                          @RequestParam(name = "serialNumber")String serialNumber) {
        DataBuffer.getBroadcast().addPopMsg(new PopMsg(
                PopType.DELIVER,
                RobotType.ROBOT,
                serialNumber,
                "Start Delivering! Order number: " + orderNumber
        ));
        System.out.println(orderNumber+","+serialNumber);
        deliveryRecordService.save(new DeliveryRecord(serialNumber,orderNumber));
        Response response = new Response();
        response.setMessage("Deliver Start");
        return response;
    }
    @GetMapping("/deliver_generated")
    public Response deliverGenerated(){
        Response response = new Response();

        return response;
    }

    @GetMapping("/unprocessed")
    public Response unprocessed() {
        List<DeliveryRecord>deliveryRecords =  deliveryRecordService.getDeliveryRecordsByStatus(0);
        List<Map<String,Object>> deliveryRecordList = new ArrayList<>();
        for (DeliveryRecord deliveryRecord : deliveryRecords) {
            deliveryRecordList.add(deliveryRecord.toMap());
        }
        Map<String,Object> map = new HashMap<>();
        map.put("recordList", deliveryRecordList);
        return new Response(200,"",map);
    }

    @GetMapping("/get")
    public Response getDeliveryRecord(@RequestParam(required = false) String serialNumber, @RequestParam(required = false) String orderNumber) {
         List<DeliveryRecord>deliveryRecords;
         if (StringIsNull(serialNumber) && StringIsNull(orderNumber)) {
                deliveryRecords= deliveryRecordService.getAll();
         }
         else if (!StringIsNull(serialNumber) && !StringIsNull(orderNumber)) {
                deliveryRecords=deliveryRecordService.getDeliveryBySerialNumberAndOrderNumber(serialNumber, orderNumber);

         }
         else  if (!StringIsNull(serialNumber)) {
                deliveryRecords=deliveryRecordService.getDeliveryBySerialNumber(serialNumber);
         }
         else {
                deliveryRecords=deliveryRecordService.getDeliveryByOrderNumber(orderNumber);
         }



        List<Map<String,Object>> deliveryRecordList = new ArrayList<Map<String,Object>>();
        for (DeliveryRecord deliveryRecord : deliveryRecords) {
            deliveryRecordList.add(deliveryRecord.toMap());
        }

        Map<String,Object>returnMap = new HashMap<>();
        returnMap.put("recordList",deliveryRecordList);
        return new Response(200,"", returnMap);

    }

}
